﻿using System;
using ProjectAutumn.Graphics;
using Tao.Sdl;

namespace ProjectAutumn.GraphicsDevice.SDL
{
    class SDLGraphicsDevice : Graphics.GraphicsDevice
    {
        private IntPtr mainSurface;
        private unsafe Sdl.SDL_Surface* surface;
        public SDLGraphicsDevice(Game game)
                : base(game) {}
        public override void Clear(Color color)
        {
            Sdl.SDL_Rect rect = new Sdl.SDL_Rect(0, 0, (short)Width, (short)Height);
            Sdl.SDL_FillRect(mainSurface, ref rect, color.PackedValue);
        }
        protected override Texture LoadTexture(string file) { return new SDLTexture(file); }
        protected override void BeginDraw() { }
        public override void Begin2D() { }
        public override void End2D()
        {
            Sdl.SDL_Flip(mainSurface);
        }
        public override void Draw(Texture texture, Vector2 position, Rectangle? source, Color tint, float rotation, Vector2 offset, float scale)
        {
            if (rotation != 0) throw new NotImplementedException("SDL Graphics Device doesn't yet support rotation.");
            if (scale != 1) throw new NotImplementedException("SDL Graphics Device doesn't yet support scaling.");
            if (tint != Color.White) throw new NotImplementedException("SDL Graphics Device doesn't yet tinting.");
            SDLTexture tex = (SDLTexture)texture;
            Sdl.SDL_Rect sourceRect = new Sdl.SDL_Rect(0, 0, (short)tex.Width, (short)tex.Height);
            if(source != null)
            {
                sourceRect.x = (short)source.Value.X;
                sourceRect.y = (short)source.Value.Y;
                sourceRect.w = (short)source.Value.Width;
                sourceRect.h = (short)source.Value.Height;
            }
            Sdl.SDL_Rect destRect = new Sdl.SDL_Rect((short)(position.X - offset.X), (short)(position.Y - offset.Y), (short)tex.Width, (short)tex.Height);
            Sdl.SDL_BlitSurface(tex.Handle, ref sourceRect, mainSurface, ref destRect);
        }
        protected override void EndDraw() { }
        public override unsafe int Width
        {
            get { return surface->w; }
        }
        public override unsafe int Height
        {
            get { return surface->h; }
        }
        public override Texture CreateTexture(int width, int height)
        {
            return new SDLTexture(width, height);
        }
        protected override void SetMouseVisibility(bool value)
        {
            Sdl.SDL_ShowCursor(value ? 1 : 0);
        }
        protected override unsafe void ApplyChanges(int width, int height, bool isFullscreen)
        {
            mainSurface = Game.WindowDevice.Handle;
            surface = (Sdl.SDL_Surface*)mainSurface.ToPointer();
        }
        public override GraphicCapabilities GraphicCapabilities
        {
            get {
                return new GraphicCapabilities
                {
                        SupportsChangingMouseVisibility = true,
                        SupportsClearing = true,
                        SupportsDrawing2D = true,
                        SupportsDrawingRotation = false,
                        SupportsDrawingScale = false,
                        SupportsDrawingSource = true,
                        SupportsDrawingTint = false,
                        SupportsDynamicTextures = true,
                        SupportsFullscreen = true,
                        SupportsLoadingTextureFile = true,
                        SupportsTextureSetData = true,
                };
            }
        }
    }
}
